using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace WindowsControl
{
	/// <summary>
	/// Summary description for UserControl1.
	/// </summary>
	public delegate void PosEventHandler(object sender,PosEventArgs e);
	public class PosEventArgs : EventArgs
	{
		public float x = 0;
		public float y = 0;
		public int index = 0;

		public PosEventArgs(FloatPoint p,int i)
		{
			x = p.x;
			y = p.y;
			index = i;
		}
	}

	public class FloatPoint
	{
		public float x = 0;
		public float y = 0;
		public FloatPoint(){}
		public FloatPoint(float x , float y)
		{
			set (x , y);
		}
		public FloatPoint (System.Drawing.Point p)
		{
			set (p);
		}

		public void set (float x , float y)
		{
			this.x = x;
			this.y = y;
		}
		public void set (System.Drawing.Point p)
		{
			set (p.X,p.Y ); //implicit type conversion
		}
	}
	interface IRange
	{
		int ScaleToWindow(float i,int scale);
		float ScaleFromWindow(int i,int scale);
		void set(float min,float max);
		//public DummyRangeLimit();
		//public DummyRangeLimit(float max);
		//public DummyRangeLimit(float min , float max);
		float clamp(float i);
	}
	public class DummyRangeLimit : IRange
	{
		public float value =0;
		public int ScaleToWindow(float i,int scale)
		{
			return (int) (0.5 * scale);
		}
		public float ScaleFromWindow(int i,int scale)
		{
			return (float) value;
		}
		public void set(float min,float max){this.value = max;}
		public DummyRangeLimit(){}
		public DummyRangeLimit(float max){this.set(0,max);}
		public DummyRangeLimit(float min , float max){this.set(0,max);}
		public float clamp(float i)
		{
			return (float) value;	
		}
		
	}	
	public class RangeLimit : IRange
	{
		public float outputMin = 0;
		public float outputMax = 1;
		public float clampMin = 0;
		public float clampMax = 1;

		public int ScaleToWindow(float vIn,int scale)
		{
			float vOut =  (vIn - outputMin)/(outputMax - outputMin);
			//float vOut =  (vIn - clampMin)/(clampMax - clampMin);
			//if (outputMin > outputMax){ vOut = 1 - vOut ;}

			return (int) (vOut * (float) scale);
		}
		public float ScaleFromWindow(int i,int scale)
		{
			float s = (float)i/(float) scale;
			return (float)((outputMax - outputMin) * s ) + outputMin;
		}
		public void set(float min,float max)
		{
			this.outputMin = min;
			this.outputMax = max;
			if (max > min )
			{
				this.clampMin = min;
				this.clampMax = max;
			}
			else
			{
				this.clampMin = max;
				this.clampMax = min;
			}
		}
		public RangeLimit(){}
		public RangeLimit(float max)
		{
			this.set(0,max);
		}
		public RangeLimit(float min , float max)
		{
			this.set(min,max);
		}
		public static int clamp(int i,int min,int max)
		{
			if (i < min){i = min;}
			else
			{
				if(i>(max)){i = max;}
			}
			return i;
		}
		public static float clamp(float i,float min,float max)
		{
			if (i < min){i = min;}
			else
			{
				if(i>(max)){i = max;}
			}
			return i;
		}
		public float clamp(float i)
		{
			if (i < this.clampMin){i = this.clampMin;}
			else
			{
				if(i>(this.clampMax)){i = this.clampMax;}
			}
			return i;
		}
	}
}
